#include "MessageSubscriber.h"

#include <fastdds/dds/domain/DomainParticipantFactory.hpp>
#include <fastdds/dds/subscriber/qos/DataReaderQos.hpp>
#include <fastdds/rtps/transport/TCPv4TransportDescriptor.h>
//#include <fastrtps/utils/IPLocator.h>

using namespace eprosima::fastdds::dds;
using namespace eprosima::fastdds::rtps;

using IPLocator = eprosima::fastrtps::rtps::IPLocator;
bool MessageSubscriber_tcp::init(InitParam param) {
    DomainParticipantQos pqos;
    Locator initial_peer_locator;
    initial_peer_locator.kind = LOCATOR_KIND_TCPv4;
    listener_->zeroCopy_ = param.zeroCopy;
    if (!param.wan_ip.empty())
    {
        //IPLocator::setIPv4(initial_peer_locator, "");
        std::cout << param.wan_ip << ":" << param.port << std::endl;
    }
    else
    {
        //IPLocator::setIPv4(initial_peer_locator, "127.0.0.1");
    }
    initial_peer_locator.port = param.port;
    pqos.wire_protocol().builtin.initialPeersList.push_back(initial_peer_locator); // Publisher's meta channel

    pqos.wire_protocol().builtin.discovery_config.leaseDuration = eprosima::fastrtps::c_TimeInfinite;
    pqos.wire_protocol().builtin.discovery_config.leaseDuration_announcementperiod = Duration_t(5, 0);
    pqos.name("DomainParticipant_pub_tcp");

    pqos.transport().use_builtin_transports = false;
    std::shared_ptr<TCPv4TransportDescriptor> descriptor = std::make_shared<TCPv4TransportDescriptor>();
    descriptor->interfaceWhiteList = param.whitelist;
    if (param.use_tls)
    {
        using TLSVerifyMode = TCPTransportDescriptor::TLSConfig::TLSVerifyMode;
        using TLSOptions = TCPTransportDescriptor::TLSConfig::TLSOptions;
        descriptor->apply_security = true;
        descriptor->tls_config.verify_file = "cacert.pem";
        descriptor->tls_config.verify_mode = TLSVerifyMode::VERIFY_PEER;
        descriptor->tls_config.add_option(TLSOptions::DEFAULT_WORKAROUNDS);
    }
    pqos.transport().user_transports.push_back(descriptor);
    participant_ = DomainParticipantFactory::get_instance()->create_participant(0, pqos);
    if (participant_ == nullptr)
    {
        return false;
    }

    //REGISTER THE TYPE
    type_.register_type(participant_);

    //CREATE THE SUBSCRIBER
    subscriber_ = participant_->create_subscriber(SUBSCRIBER_QOS_DEFAULT);
    if (subscriber_ == nullptr)
    {
        return false;
    }

    //CREATE THE TOPIC
    topic_ = participant_->create_topic(param.topic, "HelloWorld", TOPIC_QOS_DEFAULT);
    if (topic_ == nullptr)
    {
        return false;
    }
    //CREATE THE DATAREADER
    DataReaderQos rqos;
    rqos.history().kind = KEEP_LAST_HISTORY_QOS;
    rqos.history().depth = param.depth;
    rqos.resource_limits().max_samples = param.max_samples;
    rqos.resource_limits().allocated_samples = param.allocated_samples;
    rqos.reliability().kind = RELIABLE_RELIABILITY_QOS;
    rqos.durability().kind = TRANSIENT_LOCAL_DURABILITY_QOS;
    listener_ = new SubListener;
    reader_ = subscriber_->create_datareader(topic_, rqos, listener_);

    if (reader_ == nullptr)
    {
        return false;
    }

    return true;
}